package br.com.centrodata.interceptor;

import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.ioc.RequestScoped;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.centrodata.controller.HomeController;
import br.com.centrodata.dao.UserDao;

/**
 * Interceptor to check if the user is in the session.
 */
@Intercepts
@RequestScoped
public class AuthorizationInterceptor implements Interceptor {

    private final SessionInfo sessionInfo;
    private final UserDao  dao;
    private final Result result;

    public AuthorizationInterceptor(SessionInfo sessionInfo, UserDao dao, Result result) {
        this.sessionInfo   = sessionInfo;
        this.dao    = dao;
        this.result = result;
    }

    /**
     * the easiest way to implement the accepts method is creating an annotation
     */
    @Override
    public boolean accepts(ResourceMethod method) {
        return !method.containsAnnotation(Public.class);
    }

    /**
     * Intercepts the request and checks if there is a user logged in.
     */
    @Override
    public void intercept(InterceptorStack stack, ResourceMethod method, Object resourceInstance)
            throws InterceptionException {
        /**
         * You can use the result even in interceptors.
         */
        if (sessionInfo.getUser() == null) {
            // remember added parameters will survive one more request, when there is a redirect
            //result.include("errors", Arrays.asList(new ValidationMessage("Usuário não esta conectado", "participante")));
            result.redirectTo(HomeController.class).login();
        } else {
            dao.refresh(sessionInfo.getUser());
            // continues execution
            stack.next(method, resourceInstance);
        }
    }
}
